home *** CD-ROM | disk | FTP | other *** search
- #include <alloca.h>
- #include <newt.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <unistd.h>
-
- #include "devices.h"
- #include "install.h"
- #include "lilo.h"
- #include "log.h"
- #include "run.h"
- #include "windows.h"
-
- #ifdef __i386__
- static char * kernelPath = "/boot/vmlinuz";
- #elif __sparc__
- static char * kernelPath = "/boot/vmlinux.gz";
- #else
- #error unsupported architecture
- #endif
-
- static int mkinitrd(char * kernelVersion) {
- char * argv[] = { "/sbin/mkinitrd", "/boot/initrd", "--ifneeded",
- kernelVersion, NULL };
- int rc;
- static alreadyHappened = 0;
-
- #ifdef __sparc__
- return 0;
- #endif
-
- if (alreadyHappened) return 0;
-
- if (!access("/mnt/boot/initrd", X_OK)) {
- logMessage("/mnt/boot/initrd exists -- moving to "
- "/mnt/boot/initrd.orig");
- rename("/mnt/boot/initrd", "/mnt/boot/initrd.orig");
- }
-
- if (loadModule("loop", DRIVER_OTHER, DRIVER_MINOR_NONE, NULL))
- return INST_ERROR;
-
- winStatus(32, 3, "LILO", "Creating initial ramdisk...");
- rc = runProgramRoot(RUN_LOG, "/mnt", "/sbin/mkinitrd", argv);
- newtPopWindow();
-
- removeModule("loop");
-
- if (rc) {
- unlink("/mnt/boot/initrd");
- } else {
- alreadyHappened = 1;
- }
-
- return rc;
- }
-
- #define SKIP_LILO 1000
-
- #if defined(__i386__)
- static int liloWhere(char * hdName, char * bootDevice, char ** where) {
- newtComponent form, okay, listbox, cancel, answer, skip;
- char * format = "/dev/%-7s %s";
- char buf[200];
- void * which;
-
- newtOpenWindow(12, 6, 55, 11, "Lilo Installation");
-
- form = newtForm(NULL, NULL, 0);
- newtFormAddComponent(form,
- newtLabel(1, 1, "Where do you want to install "
- "the bootloader?"));
-
- listbox = newtListbox(2, 3, 3, NEWT_LISTBOX_RETURNEXIT);
- sprintf(buf, format, hdName,
- "Master Boot Record");
- newtListboxAddEntry(listbox, buf, (void *) 1);
- sprintf(buf, format, bootDevice,
- "First sector of boot partition");
- newtListboxAddEntry(listbox, buf, (void *) 2);
- sprintf(buf, format, "fd0",
- "First sector of a floppy disk");
- newtListboxAddEntry(listbox, buf, (void *) 3);
-
- okay = newtButton(6, 7, "Ok");
- skip = newtButton(22, 7, "Skip");
- cancel = newtButton(38, 7, "Cancel");
- newtFormAddComponents(form, listbox, okay, skip, cancel, NULL);
-
- answer = newtRunForm(form);
-
- which = newtListboxGetCurrent(listbox);
-
- newtFormDestroy(form);
- newtPopWindow();
-
- if (answer == cancel) return INST_CANCEL;
- if (answer == skip) return SKIP_LILO;
-
- switch ((int) which) {
- case 1: *where = hdName; break;
- case 2: *where = bootDevice; break;
- case 3: *where = "fd0"; break;
- }
-
- return 0;
- }
- #elif defined(__sparc__)
- static int liloWhere(char * hdName, char * bootDevice, char ** where) {
- newtComponent text, yes, no, cancel, f, answer;
- int rc;
-
- newtOpenWindow(18, 6, 42, 10, "SILO Installation");
-
- text = newtTextbox(1, 1, 40, 3, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text,
- "Would you like to install or configure the SILO bootloader on "
- "your system?");
-
- yes = newtButton(3, 6, " Yes ");
- no = newtButton(16, 6, " No ");
- cancel = newtButton(29, 6, "Cancel");
-
- f = newtForm(NULL, NULL, 0);
- newtFormAddComponents(f, text, yes, no, cancel, NULL);
-
- answer = newtRunForm(f);
- if (answer == f)
- answer = newtFormGetCurrent(f);
-
- newtPopWindow();
- newtFormDestroy(f);
-
- if (answer == yes) {
- *where = bootDevice;
- rc = 0;
- } else if (answer == cancel) {
- rc = INST_CANCEL;
- return INST_CANCEL;
- } else {
- rc = SKIP_LILO;
- }
-
- return rc;
- }
- #endif
-
- static void editBootLabel(struct partition * item) {
- newtComponent form, entry, okay, cancel, clear, answer;
- char buf[50];
- char * entryValue;
-
- newtOpenWindow(10, 7, 50, 10, "Edit Boot Label");
-
- form = newtForm(NULL, NULL, 0);
-
- strcpy(buf,"Device : /dev/");
- strcat(buf, item->device);
- newtFormAddComponent(form, newtLabel(1, 1, buf));
- newtFormAddComponent(form, newtLabel(1, 3, "Boot label :"));
-
- entry = newtEntry(17, 3, item->bootLabel, 20, &entryValue,
- NEWT_ENTRY_SCROLL | NEWT_ENTRY_RETURNEXIT);
-
- okay = newtButton(5, 6, "Ok");
- clear = newtButton(20, 6, "Clear");
- cancel = newtButton(35, 6, "Cancel");
-
- newtFormAddComponents(form, entry, okay, clear, cancel, NULL);
-
- do {
- answer = newtRunForm(form);
-
- if (answer == clear)
- newtEntrySet(entry, "", 1);
- } while (answer == clear);
-
- if (answer != cancel) {
- if (item->bootLabel) free(item->bootLabel);
-
- if (strlen(entryValue))
- item->bootLabel = strdup(entryValue);
- else
- item->bootLabel = NULL;
- }
-
- newtPopWindow();
- }
-
- static int doinstallLilo(char * prefix, char * dev, char * rootdev,
- struct partitionTable table,
- char * append, char * kernelVersion,
- char * hdname, int linear) {
- char filename[100];
- FILE * f;
- char * argv[] = { "/mnt/sbin/lilo", NULL };
- int i;
- int rc;
- struct stat sb;
- int useInitrd = 0;
- struct partition * root = NULL;
-
- if (mkinitrd(kernelVersion))
- return INST_ERROR;
-
- if (!stat("/mnt/boot/initrd", &sb))
- useInitrd = 1;
-
- #ifdef __sparc__
- sprintf(filename, "%s/silo.conf", prefix);
- #else
- sprintf(filename, "%s/lilo.conf", prefix);
- #endif
-
- /* why not? */
- rename("/mnt/etc/lilo.conf", "/mnt/etc/lilo.conf.orig");
- rename("/mnt/etc/silo.conf", "/mnt/etc/silo.conf.orig");
-
- f = fopen(filename, "w");
- if (!f) {
- errorWindow("cannot create [ls]ilo config file: %s");
- return INST_ERROR;
- }
-
- logMessage("writing [sl]ilo config to %s", filename);
-
- for (i = 0; i < table.count; i++) {
- if (table.parts[i].bootLabel &&
- table.parts[i].type == PART_EXT2) {
- root = table.parts + i;
- }
- }
-
- if (!root) {
- errorWindow("No ext2 partition is bootable");
- return INST_ERROR;
- }
-
- #ifdef __i386__
- fprintf(f, "boot=/dev/%s\n", dev);
- fprintf(f, "map=/boot/map\n");
- fprintf(f, "install=/boot/boot.b\n");
- fprintf(f, "prompt\n");
- if (linear) fprintf(f, "linear\n");
- fprintf(f, "timeout=50\n");
- #elif __sparc__
- fprintf(f, "timeout=50\n");
- fprintf(f, "partition=%s\n", root->device + 3);
- fprintf(f, "root=/dev/%s\n", root->device);
- #else
- #error "unsupported architecture";
- #endif
-
- for (i = 0; i < table.count; i++) {
- if (table.parts[i].bootLabel) {
- if (table.parts[i].type == PART_EXT2) {
- fprintf(f, "image=%s\n", kernelPath);
- fprintf(f, "\tlabel=%s\n", table.parts[i].bootLabel);
-
- /* we can setup a /boot on the fresh system if we need to */
- if (!strcmp(table.parts[i].device, dev))
- fprintf(f, "\troot=/dev/%s\n", rootdev);
- else
- fprintf(f, "\troot=/dev/%s\n", table.parts[i].device);
- if (useInitrd)
- fprintf(f, "\tinitrd=/boot/initrd\n");
- if (append) fprintf(f, "\tappend=\"%s\"\n", append);
- fprintf(f, "\tread-only\n");
- #ifdef __i386__
- } else {
- fprintf(f, "other=/dev/%s\n", table.parts[i].device);
- fprintf(f, "\tlabel=%s\n", table.parts[i].bootLabel);
- fprintf(f, "\ttable=/dev/%.3s\n", table.parts[i].device);
- if (strncmp(table.parts[i].device, hdname, 3))
- fprintf(f, "\tloader=/boot/any_d.b\n");
- #endif
- }
- }
- }
-
- fclose(f);
-
- winStatus(35, 3, "Running", "Installing boot loader...");
-
- #ifdef __i386__
- rc = runProgramRoot(RUN_LOG, "/mnt", "sbin/lilo", argv);
- #elif __sparc__
- rc = doMount("/proc", "/mnt/proc", "proc", 0, 0);
- if (rc) {
- newtPopWindow();
- return rc;
- }
- rc = runProgramRoot(RUN_LOG, "/mnt", "sbin/silo", argv);
- umount("/mnt/proc");
- #else
- #error unsupported architectures
- #endif
-
- newtPopWindow();
-
- if (rc)
- return INST_ERROR;
-
- return 0;
- }
-
- static int getBootLabels(struct partitionTable table, struct fstab fstab) {
- newtComponent f, okay, text, listbox, label, cancel, edit, answer;
- char buf[80];
- int i, j;
- int foundDos = 0;
- int mustAsk = 0;
- int * map;
- struct partition * curr;
- int * currNum;
- int count;
-
- f = newtForm(NULL, NULL, 0);
- text = newtTextbox(1, 1, 60, 4, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text,
- "The boot manager Red Hat uses can boot other "
- "operating systems as well. You need to tell me "
- "what partitions you would like to be able to boot "
- "and what label you want to use for each of them.");
-
-
- sprintf(buf, "%-10s %-25s %-18s", "Device", "Partition type",
- "Boot label");
- label = newtLabel(1, 6, buf);
-
- listbox = newtListbox(1, 7, 7, NEWT_LISTBOX_RETURNEXIT);
- map = alloca(sizeof(int) * table.count);
-
- for (i = 0, count = 0; i < table.count; i++) {
- if (table.parts[i].type != PART_SWAP &&
- table.parts[i].type != PART_IGNORE &&
- #ifdef __sparc__
- table.parts[i].type != PART_OTHER &&
- #endif
- (table.parts[i].type != PART_DOS || !foundDos)) {
-
- if (table.parts[i].type == PART_DOS) {
- table.parts[i].bootLabel = strdup("dos");
- foundDos = 1;
- }
-
- if (table.parts[i].type == PART_EXT2) {
- for (j = 0; j < fstab.numEntries; j++) {
- if (!strcmp(table.parts[i].device, fstab.entries[j].device))
- break;
- }
-
- if (j < fstab.numEntries && !table.parts[i].bootLabel)
- continue;
- }
-
- if (!table.parts[i].bootLabel ||
- strcmp(table.parts[i].bootLabel, "linux")) mustAsk = 1;
-
- sprintf(buf, "/dev/%-5s %-25s %-18s", table.parts[i].device,
- table.parts[i].tagName, table.parts[i].bootLabel ?
- table.parts[i].bootLabel : "");
- map[count] = i;
- newtListboxAddEntry(listbox, buf, map + count++);
- }
- }
-
- newtFormAddComponents(f, text, label, listbox, NULL);
-
- if (!mustAsk) {
- newtFormDestroy(f);
- return 0;
- }
-
- newtOpenWindow(8, 2, 64, 19, "Bootable Partitions");
-
- okay = newtButton(8, 15, "Ok");
- edit = newtButton(26, 15, "Edit");
- cancel = newtButton(44, 15, "Cancel");
-
- newtFormAddComponents(f, okay, edit, cancel, NULL);
-
- do {
- answer = newtRunForm(f);
- if (answer == edit || answer == listbox) {
- currNum = newtListboxGetCurrent(listbox);
- curr = table.parts + *currNum;
- editBootLabel(curr);
- sprintf(buf, "/dev/%-5s %-25s %-18s", curr->device,
- curr->tagName,
- curr->bootLabel ? curr->bootLabel : "");
-
- newtListboxSetEntry(listbox, currNum - map, buf);
- }
- } while (answer == edit || answer == listbox);
-
- newtFormDestroy(f);
- newtPopWindow();
-
- if (answer == cancel)
- return INST_CANCEL;
- else
- return 0;
- }
-
- static int getAppendLine(char ** line, int * linear) {
- newtComponent form, text, entry, okay, cancel, answer;
- newtComponent linearCheck;
- char * result = NULL;
- char linearChar = (*linear) ? '*' : ' ';
- int buttonLine = 9;
-
- #ifdef __sparc__
- newtOpenWindow(12, 5, 55, 13, "Silo Installation");
- #else
- /* this is bigger on the Intel to leave room for the linear checkbox */
- newtOpenWindow(12, 5, 55, 15, "Lilo Installation");
- #endif
-
- form = newtForm(NULL, NULL, 0);
- text = newtTextbox(1, 1, 53, 5, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text,
- "A few systems will need to pass special options "
- "to the kernel at boot time for the system to function "
- "properly. If you need to pass boot options to the "
- "kernel, enter them now. If you don't need any or "
- "aren't sure, leave this blank.");
-
- entry = newtEntry(1, 7, *line, 48, &result,
- NEWT_ENTRY_SCROLL | NEWT_ENTRY_RETURNEXIT);
-
- #ifndef __sparc__
- buttonLine = 11;
- linearCheck = newtCheckbox(1, 9,
- "Use linear mode (needed for some SCSI drives)",
- linearChar, NULL, &linearChar);
- #endif
-
- okay = newtButton(12, buttonLine, "Ok");
- cancel = newtButton(35, buttonLine, "Cancel");
-
- newtFormAddComponents(form, text, entry, NULL);
- #ifndef __sparc__
- newtFormAddComponent(form, linearCheck);
- #endif
- newtFormAddComponents(form, okay, cancel, NULL);
- newtFormSetCurrent(form, okay);
-
- answer = newtRunForm(form);
-
- newtPopWindow();
-
- if (answer == cancel) {
- newtFormDestroy(form);
- return INST_CANCEL;
- }
-
- *linear = linearChar != ' ';
-
- if (!strlen(result))
- *line = NULL;
- else
- *line = strdup(result);
-
- newtFormDestroy(form);
-
- return 0;
- }
-
- #define LILO_WHERE 2
- #define LILO_LABELS 3
- #define LILO_INSTALL 4
- #define LILO_APPEND 5
- #define LILO_DONE 20
-
- int installLilo(char * prefix, struct partitionTable table,
- struct fstab fstab, char * kernelVersion) {
- char * rootDevice, * bootDevice = NULL;
- char * hdName;
- char * where;
- char * append = NULL;
- char * chptr = NULL;
- int i;
- int rc;
- int stage = LILO_WHERE;
- static int linear = 0;
-
- hdName = alloca(4);
- strncpy(hdName, table.parts[0].device, 3);
- hdName[3] = '\0';
-
- for (i = 0; i < fstab.numEntries; i++) {
- if (!strcmp(fstab.entries[i].mntpoint, "/boot")) break;
- }
-
- if (i < fstab.numEntries)
- bootDevice = fstab.entries[i].device;
-
- for (i = 0; i < fstab.numEntries; i++) {
- if (!strcmp(fstab.entries[i].mntpoint, "/")) break;
- }
-
- rootDevice = fstab.entries[i].device;
- if (!bootDevice) {
- bootDevice = rootDevice;
- }
-
- for (i = 0; i < table.count; i++) {
- if (!strcmp(table.parts[i].device, bootDevice)) {
- table.parts[i].bootLabel = strdup("linux");
- break;
- }
- }
-
- while (stage != LILO_DONE) {
- switch (stage) {
- case LILO_WHERE:
- rc = liloWhere(hdName, bootDevice, &where);
- if (rc == SKIP_LILO ) return 0;
- if (rc) return rc;
- stage = LILO_APPEND;
- break;
-
- case LILO_APPEND:
- chptr = append;
- rc = getAppendLine(&chptr, &linear);
-
- if (rc == INST_ERROR) return INST_ERROR;
- if (rc == INST_CANCEL)
- stage = LILO_WHERE;
- else {
- stage = LILO_LABELS;
-
- if (append) free(append);
- if (chptr) {
- append = alloca(strlen(chptr) + 1);
- strcpy(append, chptr);
- free(chptr);
- } else {
- append = NULL;
- }
- }
-
- break;
-
- case LILO_LABELS:
- rc = getBootLabels(table, fstab);
- if (rc == INST_ERROR) return INST_ERROR;
- if (rc == INST_CANCEL)
- stage = LILO_APPEND;
- else
- stage = LILO_INSTALL;
- break;
-
- case LILO_INSTALL:
- rc = doinstallLilo(prefix, where, rootDevice, table, append,
- kernelVersion, hdName, linear);
- if (rc == INST_ERROR) return INST_ERROR;
- stage = LILO_DONE;
- break;
- }
- }
-
- return 0;
- }
-